/**
 * Copyright (c) Software Institute of PKU
 * All rights reserved. 
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 */
package edu.pku.sei.modeler.actions;

import java.util.List;

import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.ui.actions.ActionRegistry;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.ui.PlatformUI;

import edu.pku.sei.modeler.actions.registry.EditorActionGroup;
import edu.pku.sei.modeler.actions.registry.IActionProvider;
import edu.pku.sei.modeler.actions.registry.TreeViewActionGroup;
import edu.pku.sei.modeler.contextmenu.ConfigLocationMgrAction;
import edu.pku.sei.modeler.contextmenu.ConfigNotationAction;
import edu.pku.sei.modeler.contextmenu.RebuildRelationAction;
import edu.pku.sei.modeler.editparts.MetaClassEditPart;
import edu.pku.sei.modeler.internal.MetaModelingProject;
import edu.pku.sei.modeler.model.core.MetaComment;
import edu.pku.sei.modeler.model.core.MetaGeneralization;
import edu.pku.sei.modeler.model.core.MetaModel;
import edu.pku.sei.modeler.model.core.MetaModelElement;
import edu.pku.sei.modeler.model.core.MetaNamedElement;
import edu.pku.sei.modeler.model.core.MetaPackage;
import edu.pku.sei.modeler.model.core.MetaReference;
import edu.pku.sei.modeler.model.structure.MetaDiagram;
import edu.pku.sei.modeler.model.structure.MetaNode;
/**
 * @author zhaoyi
 *
 */
public class MetaModelActionProvider implements IActionProvider {
	public MetaModelActionProvider( ){
		
	}
	
	@Override
	public Action getTreeViewerDoubleClickAction(Object selectedElement) {
		if(selectedElement instanceof MetaDiagram) {
			OpenDiagramAction opa = new OpenDiagramAction();
			opa.setTreeObj(selectedElement);
			return opa;
		}
		else if(selectedElement instanceof MetaModelElement) {
			OpenElementAction opa = new OpenElementAction();
			opa.setTreeObj(selectedElement);
			opa.setWorkbenchPage(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage());
			return opa;
		}
		return null;
	}
	
	@Override
	public TreeViewActionGroup getTreeViewerMenuActionGroup(TreeViewer tv) {
		return new MetaModelTreeViewActionProvider(tv);
	}
	
	@Override
	public String getProjectNature() {
		// TODO Auto-generated method stub
		return MetaModelingProject.PROJECT_NATURE;
	}
	
	private class MetaModelTreeViewActionProvider extends TreeViewActionGroup {

		public MetaModelTreeViewActionProvider(TreeViewer tv) {
			super(tv);
		}

		@Override
		public void fillContextMenu(IMenuManager menu) {
			List selectedElement = super.getSelection();
			
			if(selectedElement.size() < 1)
				return;
			Object treeObj = selectedElement.get(0);
			if (treeObj instanceof MetaGeneralization || treeObj instanceof MetaReference) {
				NodeDeleteAction nodeDeleteAction = new NodeDeleteAction();
				nodeDeleteAction.setTreeObj(treeObj);
				menu.add(nodeDeleteAction);
			}
			
			//project
			else if (treeObj instanceof MetaModelingProject) {
				CodeGenerationAction codeGenerationAction = new CodeGenerationAction();
				codeGenerationAction.setTreeObj(treeObj);
				menu.add(codeGenerationAction);
				
				ModelCheckAction modelCheckAction = new ModelCheckAction();
				modelCheckAction.setObj(treeObj);
				menu.add(modelCheckAction);
			}
			
			
			//comment
			else if (treeObj instanceof MetaComment ) {
				NodeDeleteAction nodeDeleteAction = new NodeDeleteAction();
				nodeDeleteAction.setTreeObj(treeObj);
				menu.add(nodeDeleteAction);
			}
			

			//NamedElement,including MetaDiagram and MetaPackage
			else if (treeObj instanceof MetaNamedElement) {
				NodeRenameAction nodeRenameAction = new NodeRenameAction();
				nodeRenameAction.setTreeObj(treeObj);
				menu.add(nodeRenameAction);
				
				if (((MetaNamedElement)treeObj).getContainer() instanceof MetaModel) {
					DiagramCreateAction diagramCreateAction = new DiagramCreateAction("meta");
					diagramCreateAction.setTreeObj(treeObj);
					menu.add(diagramCreateAction);
					
				}else {
					NodeDeleteAction nodeDeleteAction = new NodeDeleteAction();
					nodeDeleteAction.setTreeObj(treeObj);
					menu.add(nodeDeleteAction);
					
					if (treeObj instanceof MetaPackage) {
						DiagramCreateAction diagramCreateAction = new DiagramCreateAction("meta");
						diagramCreateAction.setTreeObj(treeObj);
						menu.add(diagramCreateAction);
						
						ModelCheckAction modelCheckAction = new ModelCheckAction();
						modelCheckAction.setObj(treeObj);					
						menu.add(modelCheckAction);
					}
					
				}
			}
		}
		
	}

	@Override
	public EditorActionGroup getEditorActionGroup(EditPartViewer viewer,
			ActionRegistry defaultActions, MetaDiagram diagram) {
		// TODO Auto-generated method stub
		return new MetaModelEditorActionGroup(viewer, defaultActions, diagram);
	}
	
	private class MetaModelEditorActionGroup extends EditorActionGroup {

		public MetaModelEditorActionGroup(EditPartViewer viewer,
				ActionRegistry defaultActions, MetaDiagram diagram) {
			super(viewer, defaultActions, diagram);
			// TODO Auto-generated constructor stub
		}

		@Override
		public void fillContextMenu(IMenuManager menu) {
			this.fillDefaultActions(menu);
			JPEGExportAction eAction = new JPEGExportAction();
			menu.add(eAction);
		
			List list = (List) getViewer().getSelectedEditParts();
			if(list.size() == 1) {
				if(list.get(0) instanceof MetaClassEditPart) {
					Object model = ((MetaClassEditPart)list.get(0)).getModel();
					if(model instanceof MetaNode) {
						ConfigLocationMgrAction act = 
							new ConfigLocationMgrAction();
						act.setHost((MetaNode)model);
						menu.add(act);
						ConfigNotationAction action = 
							new ConfigNotationAction((MetaNode)model);
						menu.add(action);
						RebuildRelationAction rAction = 
							new RebuildRelationAction(getViewer().getEditDomain(), (MetaNode)model);
						menu.add(rAction);
					}
				}
			}
				
			
		}
		
	}
	
}
